package com.ais.gaea.dialect;

import com.ais.gaea.AnnotationUtils;
import com.ais.gaea.ColumnType;
import com.ais.gaea.annotation.TableColumn;
import com.ais.gaea.constant.Constants;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xuning
 * @date 2022/11/26
 **/
public class DMInstance extends DBInstance {
    @Override
    protected String tableOptions(Class<?> table) {
        return "";
    }

    @Override
    protected String getIdentitySql(TableColumn column) {
        return " identity(1, 1)";
    }

    @Override
    protected String getColumnTypeSql(TableColumn column) {
        StringBuilder sb = new StringBuilder();
        ColumnType type = column.type();
        switch (type) {
            case TINYINT:
            case SMALLINT:
            case INT:
            case BIGINT:
            case TEXT:
            case DATE:
                return type.toString().toLowerCase();
            case TINYINT_UNSIGNED:
                return "number(3,0)";
            case INT_UNSIGNED:
                return "number(20,0)";
            case BIGINT_UNSIGNED:
                // dm identity(1,1)自增只能和int和bigint使用，这里不能使用number(38)将其更改为无符号整数
                return "bigint";
            case VARCHAR:
                sb.append("varchar2(");
                sb.append(column.length());
                sb.append(")");
                break;
            case TIME:
                sb.append("time(");
                sb.append(column.scale());
                sb.append(")");
                break;
            case DATETIME:
                sb.append("datetime(");
                sb.append(column.scale());
                sb.append(")");
                break;
            case DECIMAL:
                sb.append("decimal(");
                sb.append(column.precision());
                sb.append(",");
                sb.append(column.scale());
                sb.append(")");
                break;
            default:
                // unexpected type
        }
        return sb.toString();
    }

    @Override
    protected String getColumnCommentSql(TableColumn column) {
        return "";
    }

    @Override
    protected List<String> tableAndColumnComment(Class<?> table) {
        StringBuilder sb = new StringBuilder();
        List<String> list = new ArrayList<>(20);
        String tableName = AnnotationUtils.getTableName(table);
        //给表增加注释
        sb.append("COMMENT ON TABLE ");
        sb.append(tableName);
        sb.append(" IS ");
        sb.append("'").append(AnnotationUtils.getTableComment(table)).append("'");
        list.add(sb.toString());

        //给字段增加注释
        TableColumn[] tableColumns = AnnotationUtils.getTableColumns(table);
        for (TableColumn tableColumn : tableColumns) {
            sb = new StringBuilder();
            sb.append("COMMENT ON COLUMN ");
            sb.append(tableName);
            sb.append(".");
            sb.append(tableColumn.name());
            sb.append(" IS ");
            sb.append("'").append(tableColumn.comment()).append("'");
            list.add(sb.toString());
        }
        return list;
    }

    @Override
    protected String getNotCluster() {
        return " Not Cluster";
    }

    @Override
    public String getExistTableSql(String schemaName) {
        return "SELECT TABLE_NAME from all_tables where owner='" + schemaName.toUpperCase() + "'";
    }

    @Override
    public String getColumnAttributeSql(String schemaName, String tableName) {
        return "select column_name,data_type,data_length,data_precision,data_scale,nullable,data_default " +
                "from all_tab_columns where Table_Name='" + tableName.toUpperCase() +
                "' and owner='" + schemaName + "'";
    }

    @Override
    public String getField() {
        return "column_name";
    }

    @Override
    public String getType() {
        return "data_type";
    }

    @Override
    public String getLength() {
        return "data_length";
    }

    @Override
    public String getPrecision() {
        return "data_precision";
    }

    @Override
    public String getScale() {
        return "data_scale";
    }

    @Override
    public String getNullable() {
        return "nullable";
    }

    @Override
    public String getDefaultValue() {
        return "data_default";
    }

    @Override
    public boolean convertNullable(String nullable) {
        return Constants.SHORT_YES.equalsIgnoreCase(nullable);
    }

    @Override
    public String convertType(String type) {
        return type;
    }

    @Override
    public String convertLength(String length) {
        return length;
    }

    @Override
    public String convertPrecision(String precision) {
        return precision;
    }

    @Override
    public String convertScale(String scale) {
        return scale;
    }

    @Override
    public String mappingColumnType(ColumnType columnType) {
        switch (columnType) {
            case TINYINT:
            case SMALLINT:
            case INT:
            case BIGINT:
            case TEXT:
            case DATE:
            case TIME:
            case DATETIME:
            case DECIMAL:
                return columnType.toString().toLowerCase();
            case TINYINT_UNSIGNED:
            case INT_UNSIGNED:
                return "number";
            case BIGINT_UNSIGNED:
                return "bigint";
            case VARCHAR:
                return "varchar2";
            default:
                //unexpected type
                return "";
        }
    }

    @Override
    public String convertDefaultValue(String defaultValue, String type) {
        defaultValue = super.convertDefaultValue(defaultValue, type);
        if (ObjectUtils.isEmpty(defaultValue)) {
            return defaultValue;
        }
        // 达梦数据库的默认值为字符型的时候，获取的时候或带上''，这里需要进行处理
        if (Constants.VARCHAR2.equalsIgnoreCase(type) ||
                ColumnType.TIME.toString().equalsIgnoreCase(type) ||
                ColumnType.DATETIME.toString().equalsIgnoreCase(type) || ColumnType.DATE.toString().equalsIgnoreCase(type)) {
            if (defaultValue.contains(Constants.SINGLE_QUOTE)) {
                defaultValue = defaultValue.replace(Constants.SINGLE_QUOTE,Constants.EMPTY_STRING);
            }
        }
        return defaultValue;
    }

}
